{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PassGAN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This Jupyter notebook is mainly for debugging, has same functionality to \"sample.py\"."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Libraries\n",
    "import os\n",
    "import time\n",
    "import pickle\n",
    "import argparse\n",
    "import tensorflow as tf\n",
    "import numpy as np\n",
    "\n",
    "# Files\n",
    "import tflib as lib\n",
    "import tflib.ops.linear\n",
    "import tflib.ops.conv1d\n",
    "import utils\n",
    "import models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.13.1\n"
     ]
    }
   ],
   "source": [
    "# TensorFlow virsion\n",
    "print(tf.__version__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Parameters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To simplify migration process between Jupyter Notebook and .py format, we created virtual ArgumentParser class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Class to virtualize ArgumentParser\n",
    "class VirtualArgparse:\n",
    "    \n",
    "    # Name of directory where pickle dictyonary is stored\n",
    "    input_dir = \"pretrained\"\n",
    "    \n",
    "    # TensorFlow checkpoint\n",
    "    checkpoint = \"pretrained/checkpoints/checkpoint_200000.ckpt\"\n",
    "    \n",
    "    # Name of file to output generated passwords\n",
    "    output = \"generated_pass.txt\"\n",
    "    \n",
    "    # Batch size\n",
    "    batch_size = 1024\n",
    "    \n",
    "    # Number of password to generate\n",
    "    num_samples = 1000000\n",
    "    \n",
    "    # Max length of password to generate (Training-Dependent)\n",
    "    seq_length = 10\n",
    "    \n",
    "    # Number of nodes on hidden layers (Training-Dependent)\n",
    "    layer_dim = 128"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Virtualize ArgumentParser instance\n",
    "args = VirtualArgparse()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Importing Dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Dictionary\n",
    "with open(os.path.join(args.input_dir, 'charmap.pickle'), 'rb') as f:\n",
    "    charmap = pickle.load(f, encoding='latin1')\n",
    "\n",
    "# Reverse-Dictionary\n",
    "with open(os.path.join(args.input_dir, 'charmap_inv.pickle'), 'rb') as f:\n",
    "    inv_charmap = pickle.load(f, encoding='latin1')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating Generator"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    }
   ],
   "source": [
    "fake_inputs = models.Generator(args.batch_size, args.seq_length, args.layer_dim, len(charmap))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Starting TensorFlow Session"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/tensorflow/python/training/saver.py:1272: checkpoint_exists (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Use standard file APIs to check for files with this prefix.\n",
      "INFO:tensorflow:Restoring parameters from pretrained/checkpoints/checkpoint_200000.ckpt\n",
      "\n",
      "Finished in 24.89 seconds\n"
     ]
    }
   ],
   "source": [
    "with tf.Session() as session:\n",
    "\n",
    "    def generate_samples():\n",
    "        samples = session.run(fake_inputs)\n",
    "        samples = np.argmax(samples, axis=2)\n",
    "        decoded_samples = []\n",
    "        for i in range(len(samples)):\n",
    "            decoded = []\n",
    "            for j in range(len(samples[i])):\n",
    "                decoded.append(inv_charmap[samples[i][j]])\n",
    "            decoded_samples.append(tuple(decoded))\n",
    "        return decoded_samples\n",
    "\n",
    "    def save(samples):\n",
    "        with open(args.output, 'a') as f:\n",
    "                for s in samples:\n",
    "                    s = \"\".join(s).replace('`', '')\n",
    "                    f.write(s + \"\\n\")\n",
    "\n",
    "    saver = tf.train.Saver()\n",
    "    saver.restore(session, args.checkpoint)\n",
    "\n",
    "    samples = []\n",
    "    then = time.time()\n",
    "    start = time.time()\n",
    "    for i in range(int(args.num_samples / args.batch_size)):\n",
    "        \n",
    "        samples.extend(generate_samples())\n",
    "\n",
    "        # append to output file every 1000 batches\n",
    "        if i % 1000 == 0 and i > 0: \n",
    "            \n",
    "            save(samples)\n",
    "            samples = [] # flush\n",
    "\n",
    "            print('wrote {} samples to {} in {:.2f} seconds. {} total.'.format(1000 * args.batch_size, args.output, time.time() - then, i * args.batch_size))\n",
    "            then = time.time()\n",
    "    \n",
    "    save(samples)\n",
    "print('\\nFinished in {:.2f} seconds'.format(time.time() - start))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Environment (conda_tensorflow_p36)",
   "language": "python",
   "name": "conda_tensorflow_p36"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
